/**
 * @constructor
 * @param {string} name
 * @param {number} index
 * @param {boolean} sync
 */
function Portfolio(name, index, visible) {
	/**
	 * The name of the portfolio
	 * @type {string}
	 */
  this.name = name;

	/**
	 * The portfolio's index (soon to be deprecated)
	 * @type {number}
	 */
  this.index = index;
	
	/**
	 * An array of quotes included in the portfolio
	 * @type {Array<Quote>}
	 */
  this.quotes = [];
	
	/**
	 * 
	 * @type {Object}
	 */
  this.$table;
	
	/**
	 * Whether the portfolio information will be visible in a table generated by
	 * a content script
	 * @type {boolean}
	 */
	this.visible = (visible === undefined ? true : visible);
}

/**
 * Adds a quote to the portfolio
 * @param {Quote} quote
 * @returns The current object
 * @type Portfolio
 */
Portfolio.prototype.add = function(quote) {
  this.quotes.push(quote);
	return this;
};

/**
 * Creates a table for editing quote information on the options page
 * @param {Node} contextNode
 */
Portfolio.prototype.editTable = function(contextNode) {
	var $div = $('<div>');
  var $table = $('<table>');
  var $thead = $('<thead>');
  var $tbody = $('<tbody>');
  var headers = ['index', 'secid', 'source', 'count', 'pricePaid', 'decimals', 'trigger'];
  var $theadTr = $('<tr>');
  
	$.each(headers, function(index, header){
    $theadTr.append($('<th>').text(Localizer.translate(header)));
	});
  $thead.append($theadTr);

  for (var i = 0; i < this.quotes.length; i++) {
    $tbody.append(this.addRow(this.quotes[i], i));
  }
  $tbody.append(this.addRow(new Quote('', 'bloomberg', 0, 0, 2, ''), i));
  
  $(contextNode).append($('<div>').append($('<input>').attr({
			placeholder: Localizer.translate('newPortfolio'),
			type: 'text'
		}).change(function(){
			var $parentDiv = $(this).parent();
			var $nextDiv = $parentDiv.next();
			if ($(this).val() === '') {
				if ($nextDiv.size() !== 0 && $('tbody tr', $parentDiv).size() === 1) {
					$parentDiv.remove();
				}
			} else {
				if ($nextDiv.size() === 0) {
					var p = new Portfolio('', 5);
					p.editTable(contextNode);
				}				
			}
		}).val(this.name))
		.append($('<button>').addClass('delete').click(function(){
			var $parentDiv = $(this).parent();
			if ($parentDiv.next().size() !== 0) {
				if (confirm(Localizer.translate('deletePortfolio'))) {
					$parentDiv.remove();
				}
			}
		})).append($('<input>').attr({
			checked: this.visible,
			id: this.name + '_visible',
			type: 'checkbox'
		})).append($('<label>').attr('for', this.name + '_visible')
			.text(Localizer.translate('makeVisible')))
		.append($table.append($thead).append($tbody)));

  this.$table = $table;
	return this;
};

/**
 * Exports the essential information in the object in JSON format
 * @return A JSON representation
 */
Portfolio.prototype.exportJSON = function(){
	var temp = [];
	$.each(this.quotes, function(index, quote){
		temp.push(quote.exportJSON());
	});
	return {
		name: this.name,
		index: this.index,
		visible: this.visible,
		quotes: temp
	};
};

/**
 * Imports a JSON object to determine the portfolio's quotes
 * @param {Array.<Object>} quotes A list of quotes to import, in JSON format
 * @return {Portfolio} The current object
 */
Portfolio.prototype.importJSON = function(quotes){
	$(quotes, function(index, quote){
		this.add(new Quote(quote.secid, quote.source, quote.count, quote.pricePaid,
			quote.decimals, quote.trigger));
	});
	return this;
};

/**
 * Creates a row for the options page based on quote information
 * @param {Object} quote The quote used to supply default values to the cells
 * created
 * @param {number} index The value to show in the index column
 * @return
 * @type Object
 */
Portfolio.prototype.addRow = function(quote, index) {
	var valueCell = function(value, maxWidth){
		return $('<td>').append($('<input>').addClass('value').attr('type', 'text')
			.css('max-width', (maxWidth !== undefined ? maxWidth : 'auto')).val(value));
	}
  var $tr = $('<tr>');

	// # column
  $tr.append($('<td>').text(index).addClass('value'));

  var parentScope = this;
  $tr.append(	$('<td>').append($('<input>').attr('type', 'text').val(quote.secid).blur(function(e){
		var $this = $(this);
		if ($this.val() === '') {
			// If security ID is blank and we're not on the last row of the table,
			// delete the current row and select the following one
			var $tr = $this.closest('tr');
			var $trNext = $tr.next('tr');
			if ($trNext.size() > 0) {
				$trNext.find('input:first').focus();
				$tr.remove();
			}
		} else {
			if ($this.closest('tr').next('tr').size() === 0) {
				console.log('adding new row');
				$this.closest('tbody').append(parentScope.addRow(new Quote('', 'bloomberg', 0, 0, 2, ''), index + 1))
			}
		}
		var $lastTr = $(this).closest('tr').siblings('tr:last');
	})));
  
	// Source column
	$tr.append(Sources.selection(this.index + '_' + index, quote.source)); //$(Sources.selection(quote.source)));
	
	// Value columns
	$tr.append(valueCell(quote.count))
  	.append(valueCell(quote.pricePaid))
		.append(valueCell(quote.decimals))
		.append(valueCell(quote.trigger, '20em'))
		.append($('<td>').append($('<button>').addClass('delete').click(function(){
			if ($tr.next().size() !== 0) {
				$tr.remove();
			}
		})));
  
  return $tr;
};